﻿using System.Linq;
using System.Web.Mvc;
using Localization;
using SinBiota.Model.Business.AuthenticationServices.Interfaces;
using SinBiota.Model.Business.PersistenceServices.Interfaces;
using SinBiota.Model.Business.ProjectServices.Interfaces;
using SinBiota.Model.Entities;
using Sinbiota.Web.ActionFilters;
using Sinbiota.Web.Models;
using System.Collections.Generic;
using System.Security.Principal; // controla a principal
using System.Threading; // controle da thread do usuário atual
using System.Security.Permissions; // controle das permissões de acesso a 

namespace Sinbiota.Web.Controllers
{
    public class ProjectController : BaseController
    {
        //Services:
        private readonly IProjectPersistenceServices _projectPersistenceServices;
        private readonly IUserPersistenceServices _userPersistenceServices;
        private readonly IProjectManagement _projectManagement;
        private readonly IPermissionServices _permissionServices;
        // Field for the keywords; also the id of the hidden fields, needed for the javascript and then here retrieving the values;
        private const string KeywordField = "KeywordField";

        public ProjectController(IProjectPersistenceServices projectPersistenceServices, IUserPersistenceServices userPersistenceServices, IProjectManagement projectManagement, IPermissionServices permissionServices)
        {
            _projectPersistenceServices = projectPersistenceServices;
            _permissionServices = permissionServices;
            _projectManagement = projectManagement;
            _userPersistenceServices = userPersistenceServices;
        }

        //
        // GET: /Project/
        [ImportMessagesFromTempData]
        public ActionResult Index()
        {
            ViewData["ProjectStatus"] = (int) ProjectStatus.InProgress;
            return View(_projectPersistenceServices.FindAllActive());
        }

        [HttpPost]
        public ActionResult Index(FormCollection collection, int projectStatus)
        {
            ViewData["ProjectStatus"] = projectStatus;
            return View (_projectPersistenceServices.FindByNameLike(collection[SearchBoxName]).Where(x => x.ProjectStatus.Equals((ProjectStatus) projectStatus)));
        }
              

        //
        // GET: /Project/Details/5
        [ImportMessagesFromTempData]
        public ActionResult Details(int id)
        {
            var project = _projectPersistenceServices.FindById(id);
            // Null, not found:
            if (project == null)
            {
                return Request.IsAjaxRequest() ? Content(Strings.PageNotFound) : (ActionResult) View("NotFound");
            }
            // Found:
            return Request.IsAjaxRequest() ? (ActionResult) PartialView("DisplayTemplates/Project", project) : View(project);
        }

        //
        // GET: /Project/Create
        [ImportMessagesFromTempData]
        [AdminPermission]
        public ActionResult Create()
        {
            return View();
        }

        //
        // POST: /Project/Create
        [HttpPost, ExportMessagesToTempData]
        [AdminPermission]
        public ActionResult Create(Project project, FormCollection collection)
        {
            var newProject = new Project();
            TryUpdateModel(newProject);

            // test if there is already an user with this username:
            if (_projectPersistenceServices.FindByName(project.Name) != null)
            {
                ModelState.AddModelError("Name", string.Format("{0}", Messages.ProjectAlreadyExists));
            }

            if (ModelState.IsValid)
            {

                // Get keyword list from hidden fields in form and Save the new project:
                var keywordList = string.IsNullOrEmpty(collection[KeywordField]) ? new string[0] : collection[KeywordField].Split(',');
                _projectPersistenceServices.Save(newProject, keywordList);
                SetInformationMessage(Messages.OperationCompletedSuccessfully);
                return RedirectToAction("Index");
            }
            return View(project);
        }

        //
        // GET: /Project/Edit/5
        [ImportMessagesFromTempData]
        [Authorize]
        public ActionResult Edit(int id)
        {
            var project = _projectPersistenceServices.FindById(id);
            return project == null ? View("NotFound") : 
                (_permissionServices.CanEditProject(User.Identity.Name, project) ? View(project) : View("NonAuthorized"));
        }

        //
        // POST: /Project/Edit/5
        [HttpPost, ExportMessagesToTempData]
        [Authorize]
        public ActionResult Edit(int id, Project project, FormCollection collection)
        {
            var editProject = _projectPersistenceServices.FindById(id);
            if (editProject == null) return View("NotFound");
            if (!_permissionServices.CanEditProject(User.Identity.Name, editProject)) return View("NonAuthorized");
            TryUpdateModel(editProject);
            if (ModelState.IsValid)
            {
                // Get keyword list from hidden fields in form and Edit the project:
                var keywordList = string.IsNullOrEmpty(collection[KeywordField]) ? new string[0] : collection[KeywordField].Split(',');
                _projectPersistenceServices.Update(editProject, keywordList);
                SetInformationMessage(Messages.OperationCompletedSuccessfully);
                return RedirectToAction("Index");
            }
            return View(project);
        }

        //
        // GET: /Project/Delete/5
        [ImportMessagesFromTempData]
        [AdminPermission]
        public ActionResult Delete(int id)
        {
            var project = _projectPersistenceServices.FindById(id);
            return project == null ? View("NotFound") : View(project);
        }

        //
        // POST: /Project/Delete/5
        [HttpPost, ExportMessagesToTempData]
        [AdminPermission]
        public ActionResult Delete(int id, FormCollection collection)
        {
            var deleteProject = _projectPersistenceServices.FindById(id);
            if (deleteProject == null) return View("NotFound");
            _projectPersistenceServices.Delete(deleteProject);
            SetInformationMessage(Messages.OperationCompletedSuccessfully);
            return RedirectToAction("Index");
        }
        [ImportMessagesFromTempData]
        [Authorize]
        public ActionResult Manage(int id)
        {
            if (!_permissionServices.CanManageProject(User.Identity.Name, id)) return View("NonAuthorized");
            var project = _projectPersistenceServices.FindById(id);
            return project == null ? View("NotFound") : View(project);
            

        }
        
        // AJAX:
        public ActionResult AddUserToProject(int id, int userId, ProjectRole projectRole)
        {
            //Get projet and users
            var project = _projectPersistenceServices.FindById(id);
            if (project == null) return Json(JsonMessage.ErrorMessage(Messages.ProjectNotFound));
            var user = _userPersistenceServices.FindById(userId);
            if (user == null) return Json(JsonMessage.ErrorMessage(Messages.UserNotFound));
            var requestingUser = _userPersistenceServices.FindByUsername(User.Identity.Name);
            if (requestingUser == null) return Json(JsonMessage.ErrorMessage(Messages.UserNotFound));
            // add user:
            switch (projectRole)
            {
                case ProjectRole.Member:
                    _projectManagement.AddProjectMember(requestingUser, project, user);
                    return Json(JsonMessage.InformationMessage(Messages.UserAddedAsProjectMember));
                case ProjectRole.Coordinator:
                    _projectManagement.AddProjectCoordinator(requestingUser, project, user);
                    return Json(JsonMessage.InformationMessage(Messages.UserAddedAsProjectCoordinator));
                default:
                    return Json(JsonMessage.ErrorMessage("Unknown Project Role"));
            }
        }

        //Get all Projects
        public JsonResult GetAll()
        {
            const int maxlength = 300;
            var list = _projectPersistenceServices.FindAll().Select(x => new { x.Id, Name = x.Name.Length > maxlength ? x.Name.Substring(0,maxlength) + "..." : x.Name}).OrderBy(i => i.Name);
            return Json(list);
        }

        public ActionResult GetMembers(int id)
        {
            return PartialView("UserList", _projectPersistenceServices.FindById(id).Members);
        }
        public ActionResult GetCoordinators(int id)
        {
            return PartialView("UserList", _projectPersistenceServices.FindById(id).Coordinators);
        }
    }
}
